package com.fast.fast.upms.biz.service.impl;

import cn.hutool.core.util.ObjUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fast.fast.common.base.exception.BizException;
import com.fast.fast.upms.api.entity.SysPerm;
import com.fast.fast.upms.api.entity.SysRolePerm;
import com.fast.fast.upms.api.vo.SysPermVO;
import com.fast.fast.upms.biz.base.face.enums.TreeEnum;
import com.fast.fast.upms.biz.base.factory.TreeConvertFactory;
import com.fast.fast.upms.biz.base.util.ClearAuthUtils;
import com.fast.fast.upms.biz.base.util.TreeUtils;
import com.fast.fast.upms.biz.mapper.SysPermMapper;
import com.fast.fast.upms.biz.service.SysPermService;
import com.fast.fast.upms.biz.service.SysRolePermService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author lyf
 * @description 针对表【sys_perm(系统权限表)】的数据库操作Service实现
 * @createDate 2022/01/01 00:00 周六
 */
@Service
public class SysPermServiceImpl extends ServiceImpl<SysPermMapper, SysPerm>
        implements SysPermService {

    @Autowired
    private TreeConvertFactory treeConvertFactory;

    @Autowired
    private ClearAuthUtils clearAuthUtils;

    @Autowired
    private SysRolePermService sysRolePermService;

    @Override
    public boolean saveOrUpdate(SysPerm sysPerm) {
        // 父节点不能是自己
        if (sysPerm.getPid().equals(sysPerm.getId())) {
            throw new BizException("父节点不能是自己");
        }
        // 如果当前节点的父节点改变时，需要重新设置排序值
        SysPerm old = getOne(Wrappers.lambdaQuery(SysPerm.class)
                .eq(SysPerm::getId, sysPerm.getId()));
        if (!sysPerm.getPid().equals(old.getPid())) {
            Integer sort = this.getMaxSortByPid(sysPerm.getPid());
            sort++;
            sysPerm.setSort(sort);
        }
        super.saveOrUpdate(sysPerm);
        // 清除所有用户的权限编码集合
        clearAuthUtils.clearAllUserPermList();
        return true;
    }

    @Override
    public List<SysPermVO> permTree() {
        // 权限集合
        List<SysPerm> sysPerms = list(Wrappers.lambdaQuery(SysPerm.class)
                .orderByAsc(SysPerm::getSort)
        );
        // 获取包括所有子节点信息的父节点
        List<SysPerm> nodes = sysPerms.stream().filter(o -> o.getPid() == 0)
                .map(o -> TreeUtils.listNodes(sysPerms, o))
                .collect(Collectors.toList());
        // 出参转换
        Object obj = treeConvertFactory.getConvert(TreeEnum.PERM_TREE).convert(nodes);
        return (List<SysPermVO>) obj;
    }

    @Override
    public synchronized boolean addRoot(SysPerm sysPerm) {
        List<SysPerm> sysPerms = list(Wrappers.lambdaQuery(SysPerm.class)
                .eq(SysPerm::getPid, 0L).select());
        // 获取根节点的最大排序值
        Integer sort = sysPerms.stream().map(SysPerm::getSort).max(Integer::compare).orElse(0);
        sort++;
        sysPerm.setSort(sort);
        save(sysPerm);
        // 清除所有用户的权限编码集合
        clearAuthUtils.clearAllUserPermList();
        return true;
    }

    @Override
    public synchronized boolean addChild(JSONObject treeNode) {
        SysPerm sysPerm = new SysPerm();
        String name = treeNode.getString("addNodeName");
        String code = treeNode.getString("addNodeCode");
        Long pid = treeNode.getLong("parentId");
        sysPerm.setName(name);
        sysPerm.setCode(code);
        sysPerm.setPid(pid);
        // 根据父节点id获取父节点层级的最大排序值
        Integer sort = this.getMaxSortByPid(sysPerm.getPid());
        sort++;
        sysPerm.setSort(sort);
        save(sysPerm);
        // 清除所有用户的权限编码集合
        clearAuthUtils.clearAllUserPermList();
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean delete(List<?> ids) {
        removeBatchByIds(ids);
        if (ObjUtil.isNotEmpty(ids)) {
            // 删除系统角色权限关联表数据
            List<Long> sysRolePermIds = sysRolePermService.list(Wrappers.lambdaQuery(SysRolePerm.class)
                    .in(SysRolePerm::getPermId, ids)
            ).stream().map(SysRolePerm::getId).collect(Collectors.toList());
            sysRolePermService.removeBatchByIds(sysRolePermIds);
        }
        // 清除所有用户的权限编码集合
        clearAuthUtils.clearAllUserPermList();
        return true;
    }

    /**
     * 根据父节点id获取父节点层级的最大排序值
     *
     * @param pid
     * @return
     */
    private synchronized Integer getMaxSortByPid(long pid) {
        List<SysPerm> sysPerms = list(Wrappers.lambdaQuery(SysPerm.class)
                .eq(SysPerm::getPid, pid));
        return sysPerms.stream().map(SysPerm::getSort).max(Integer::compare).orElse(0);
    }

}




